package org.herrdommel.wakemeup.provider;

import org.herrdommel.wakemeup.model.Alarm;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class AlarmContentProvider extends ContentProvider {

	// Loader ids
	public static final int LOADER_ALARM_LIST = 0x200;

	// Uri type ids
	private static final int ALARMS = 0x100;
	private static final int ALARM_ID = 0x110;

	// The content providers authority
	private static final String AUTHORITY = "org.herrdommel.wakemeup.provider";

	// Content uri definition
	private static final String ALARMS_BASE_PATH = "alarms";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + ALARMS_BASE_PATH);

	// Content types definition
	public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/alarms";
	public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/alarm";

	// An UriMatcher object
	private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	static {
		uriMatcher.addURI(AUTHORITY, ALARMS_BASE_PATH, ALARMS);
		uriMatcher.addURI(AUTHORITY, ALARMS_BASE_PATH + "/#", ALARM_ID);
	}

	private AlarmDatabaseHelper database;

	@Override
	public boolean onCreate() {
		database = new AlarmDatabaseHelper(getContext());
		return true;
	}

	@Override
	public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
		final int uriType = uriMatcher.match(uri);
		final SQLiteDatabase sqlDB = database.getWritableDatabase();
		int rowsAffected = 0;
		switch (uriType) {
			case ALARMS :
				rowsAffected = sqlDB.delete(Alarm.ALARMS_TABLE_NAME, selection, selectionArgs);
				break;
			case ALARM_ID :
				final String id = uri.getLastPathSegment();
				if (TextUtils.isEmpty(selection)) {
					rowsAffected = sqlDB.delete(Alarm.ALARMS_TABLE_NAME, Alarm._ID + "=" + id, null);
				} else {
					rowsAffected = sqlDB.delete(Alarm.ALARMS_TABLE_NAME, selection + " AND " + Alarm._ID + "=" + id,
							selectionArgs);
				}
				break;
			default :
				throw new IllegalArgumentException("Unknown or Invalid URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsAffected;
	}

	@Override
	public String getType(final Uri uri) {
		final int uriType = uriMatcher.match(uri);
		switch (uriType) {
			case ALARMS :
				return CONTENT_TYPE;
			case ALARM_ID :
				return CONTENT_ITEM_TYPE;
			default :
				return null;
		}
	}

	@Override
	public Uri insert(final Uri uri, final ContentValues values) {
		final int uriType = uriMatcher.match(uri);
		if (uriType != ALARMS) {
			throw new IllegalArgumentException("Invalid URI for insert");
		}
		final SQLiteDatabase sqlDB = database.getWritableDatabase();
		final long newID = sqlDB.insert(Alarm.ALARMS_TABLE_NAME, null, values);
		if (newID > 0) {
			final Uri newUri = ContentUris.withAppendedId(uri, newID);
			getContext().getContentResolver().notifyChange(uri, null);
			return newUri;
		} else {
			throw new SQLException("Failed to insert row into " + uri);
		}
	}

	@Override
	public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs,
			final String sortOrder) {
		final SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(Alarm.ALARMS_TABLE_NAME);

		final int uriType = uriMatcher.match(uri);
		switch (uriType) {
			case ALARM_ID :
				queryBuilder.appendWhere(Alarm._ID + "=" + uri.getLastPathSegment());
				break;
			case ALARMS :
				// no filter here
				break;
			default :
				throw new IllegalArgumentException("Unknown URI");
		}

		final Cursor cursor = queryBuilder.query(database.getReadableDatabase(), projection, selection, selectionArgs,
				null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	@Override
	public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
		final int uriType = uriMatcher.match(uri);
		final SQLiteDatabase sqlDB = database.getWritableDatabase();

		int rowsAffected;

		switch (uriType) {
			case ALARM_ID :
				final String id = uri.getLastPathSegment();
				final StringBuilder modSelection = new StringBuilder(Alarm._ID + "=" + id);

				if (!TextUtils.isEmpty(selection)) {
					modSelection.append(" AND " + selection);
				}

				rowsAffected = sqlDB.update(Alarm.ALARMS_TABLE_NAME, values, modSelection.toString(), null);
				break;
			case ALARMS :
				rowsAffected = sqlDB.update(Alarm.ALARMS_TABLE_NAME, values, selection, selectionArgs);
				break;
			default :
				throw new IllegalArgumentException("Unknown URI");
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsAffected;
	}

}
